package com.dz.risk.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dz.risk.dao.ReportFormsDataValueDao;
import com.dz.risk.pojo.domain.IndicatorDetailsEntity;
import com.dz.risk.pojo.domain.ReportFormsDataValueEntity;
import com.dz.risk.pojo.model.FormulaExtModel;
import com.dz.risk.pojo.model.FormulaModel;
import com.dz.risk.pojo.model.InportFormulaModel;
import com.dz.risk.service.IndicatorDetailsService;
import com.dz.risk.service.ReportFormsDataValueService;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.streaming.SXSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.URLEncoder;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 报表指标值业务处理层
 *
 * @author Doke
 */
@Service("tStReportFormsDataValueService")
public class ReportFormsDataValueServiceImpl extends ServiceImpl<ReportFormsDataValueDao, ReportFormsDataValueEntity> implements ReportFormsDataValueService {

    private final ReportFormsDataValueDao reportFormsDataValueDao;

    private final IndicatorDetailsService indicatorDetailsService;

    @Autowired
    public ReportFormsDataValueServiceImpl(ReportFormsDataValueDao reportFormsDataValueDao, IndicatorDetailsService indicatorDetailsService) {
        this.reportFormsDataValueDao = reportFormsDataValueDao;
        this.indicatorDetailsService = indicatorDetailsService;
    }

    /**
     * 根据报表ID删除报表指标数据
     *
     * @param reportFormsId 报表ID
     * @return 删除的条数
     */
    @Override
    public int deleteByReportFormsId(String reportFormsId) {
        return reportFormsDataValueDao.deleteByReportFormsId(reportFormsId);
    }

    /**
     * 根据参数查询该报表版本得模板数据内容
     *
     * @param reportFormsSerialNumber 报表编号
     * @param reportFormsBeginDate    开始时间
     * @param reportFormsEndDate      结束时间时间
     * @return 报表数据值集合
     */
    @Override
    public List<ReportFormsDataValueEntity> selectDynamicExcelVersion(String reportFormsSerialNumber, Date reportFormsBeginDate, Date reportFormsEndDate) {
        return reportFormsDataValueDao.selectDynamicExcelVersion(reportFormsSerialNumber, reportFormsBeginDate, reportFormsEndDate);
    }

    /**
     * 根据参数查询报表数据内容集合
     *
     * @param reportFormsDataValueEntity 报表数据内容实体
     * @return 报表数据内容集合
     */
    @Override
    public List<ReportFormsDataValueEntity> selectByParams(ReportFormsDataValueEntity reportFormsDataValueEntity) {
        QueryWrapper<ReportFormsDataValueEntity> wrapper = new QueryWrapper<>();
        wrapper.lambda()
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getId()), ReportFormsDataValueEntity::getId, reportFormsDataValueEntity.getId())
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getReportFormsId()), ReportFormsDataValueEntity::getReportFormsId, reportFormsDataValueEntity.getReportFormsId())
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getTableCellSerialNumber()), ReportFormsDataValueEntity::getTableCellSerialNumber, reportFormsDataValueEntity.getTableCellSerialNumber())
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getDataValue()), ReportFormsDataValueEntity::getDataValue, reportFormsDataValueEntity.getDataValue())
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getDataUnit()), ReportFormsDataValueEntity::getDataUnit, reportFormsDataValueEntity.getDataUnit())
                .eq(Objects.nonNull(reportFormsDataValueEntity.getVersion()), ReportFormsDataValueEntity::getVersion, reportFormsDataValueEntity.getVersion())
                .eq(Objects.nonNull(reportFormsDataValueEntity.getRemark()), ReportFormsDataValueEntity::getRemark, reportFormsDataValueEntity.getRemark())
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getLineNumber()), ReportFormsDataValueEntity::getLineNumber, reportFormsDataValueEntity.getLineNumber())
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getColumnNumber()), ReportFormsDataValueEntity::getColumnNumber, reportFormsDataValueEntity.getColumnNumber())
                .eq(Objects.nonNull(reportFormsDataValueEntity.getFormula()), ReportFormsDataValueEntity::getFormula, reportFormsDataValueEntity.getFormula())
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getCreatedUser()), ReportFormsDataValueEntity::getCreatedUser, reportFormsDataValueEntity.getCreatedUser())
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getCreatedTime()), ReportFormsDataValueEntity::getCreatedTime, reportFormsDataValueEntity.getCreatedTime())
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getUpdatedUser()), ReportFormsDataValueEntity::getUpdatedUser, reportFormsDataValueEntity.getUpdatedUser())
                .eq(!StringUtils.isEmpty(reportFormsDataValueEntity.getUpdatedTime()), ReportFormsDataValueEntity::getUpdatedTime, reportFormsDataValueEntity.getUpdatedTime())
                .eq(Objects.nonNull(reportFormsDataValueEntity.getDelFlag()), ReportFormsDataValueEntity::getDelFlag, reportFormsDataValueEntity.getDelFlag());
        return reportFormsDataValueDao.selectList(wrapper);
    }

    /**
     * 根据报表ID获取该报表模板数据
     *
     * @param reportFormsId 报表ID
     * @return 报表数据值集合
     */
    @Override
    public List<ReportFormsDataValueEntity> selectReportTemplateByReportFormsId(String reportFormsId) {
        return reportFormsDataValueDao.selectReportTemplateByReportFormsId(reportFormsId);
    }

    /**
     * 根据ID更新单元格公式
     *
     * @param formulaExtModel 公式扩展模型
     * @return 跟新条数
     */
    @Override
    public int updateFormulaById(FormulaExtModel formulaExtModel) {
        return reportFormsDataValueDao.updateById(ReportFormsDataValueEntity.builder().id(formulaExtModel.getReportFormsDataValueId()).formula(formulaExtModel.getCellFormula()).build());
    }

    /**
     * 根据报表版本以及单元格编号查询报表数据值
     *
     * @param tableCellSerialNumber 单元格编号
     * @param beginDate             报表开始时间
     * @param endDate               报表结束时间
     * @param dateValueVersion      数据值版本
     * @return 报表数据值集合
     */
    @Override
    public List<ReportFormsDataValueEntity> selectByReportFormsVersionAndIndexNumber(String tableCellSerialNumber, Date beginDate, Date endDate, Date dateValueVersion) {
        return reportFormsDataValueDao.selectByReportFormsVersionAndIndexNumber(tableCellSerialNumber, beginDate, endDate, dateValueVersion);
    }

    /**
     * 根据单元格编号查询数据值不为空的数据
     *
     * @param tableCellSerialNumber 单元格编号
     * @return 报表数据值集合
     */
    @Override
    public List<ReportFormsDataValueEntity> selectByCellSerialNumberAndDataValueIsNotNull(String tableCellSerialNumber) {
        return reportFormsDataValueDao.selectByCellSerialNumberAndDataValueIsNotNull(tableCellSerialNumber);
    }

    /**
     * 删除报表下相同版本的报表计算数据
     *
     * @param reportFormsId    报表ID
     * @param dataValueVersion 数据值版本
     */
    @Override
    public void deleteByReportFormsIdAndVersion(String reportFormsId, Date dataValueVersion) {
        reportFormsDataValueDao.deleteByReportFormsIdAndVersion(reportFormsId, dataValueVersion);
    }

    /**
     * 查询报表计算版本数据
     *
     * @param reportFormsId 报表ID
     * @param version       数据版本
     * @return 报表计算数据值集合
     */
    @Override
    public List<List<ReportFormsDataValueEntity>> selectReportFormsDataValueByVersion(String reportFormsId, Date version) {
        QueryWrapper<ReportFormsDataValueEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda()
                .eq(ReportFormsDataValueEntity::getReportFormsId, reportFormsId)
                .eq(ReportFormsDataValueEntity::getVersion, version);

        List<ReportFormsDataValueEntity> dataValueEntities = reportFormsDataValueDao.selectList(queryWrapper);
        return reportFormsDataValueEntitiesGroupSort(dataValueEntities);
    }

    /**
     * 根据参数查询该报表版本得模板数据内容
     *
     * @param reportFormsSerialNumber 报表编号
     * @param reportFormsBeginDate    开始时间
     * @param reportFormsEndDate      结束时间时间
     * @return 报表数据值集合
     */
    @Override
    public List<List<ReportFormsDataValueEntity>> selectReportFormsDataValueByVersionAndSerialNumber(String reportFormsSerialNumber, Date reportFormsBeginDate, Date reportFormsEndDate) {
        List<ReportFormsDataValueEntity> reportFormsDataValueEntities = selectDynamicExcelVersion(reportFormsSerialNumber, reportFormsBeginDate, reportFormsEndDate);
        return reportFormsDataValueEntitiesGroupSort(reportFormsDataValueEntities);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = RuntimeException.class)
    public void setUpTheFormula(List<InportFormulaModel> result, HttpServletRequest request) {
        //编码与中文管理
        List<IndicatorDetailsEntity> indicatorDetailsEntities = indicatorDetailsService.selectAll();
        //将编码与中文管理转换成map
        Map<String,String> resultMap = indicatorDetailsEntities.stream().collect(
                Collectors.toMap(IndicatorDetailsEntity::getIndexNumber, IndicatorDetailsEntity::getIndexName, (s, a) -> s + a));
        Map<String, String> hashMap = new HashMap<>();
        for (InportFormulaModel inportFormulaModel : result) {
            if (!StringUtils.isEmpty(inportFormulaModel.getFormulaId())) {
                Map<Long, String> map = new HashMap<>();
                /**
                 * {"value": null, "formulaDesc": "", "formulaType": "0", "parseFormula": ["901000100000201"], "formulaDetails": "901000100000201"}
                 */
                FormulaModel formulaModel = new FormulaModel();
                String formulaId = inportFormulaModel.getFormulaId();
                String lastNum = (formulaId + "").charAt((formulaId + "").length() - 1) + "";
                //类型
                formulaModel.setFormulaType(lastNum);
                //公式
                formulaModel.setFormulaDetails(inportFormulaModel.getFormulaValue());
                //parseFormula
                if (lastNum.equals("0")) {

                    //字段
                    String[] split = inportFormulaModel.getField().split(",");
                    List<String> list = new ArrayList<>();
                    //公式描述
                    String formulaValue = inportFormulaModel.getFormulaValue();
                    for (String parseFormula : split) {
                        if (!parseFormula.equals("")) {
                            list.add(parseFormula);
                        }
                        if (!StringUtils.isEmpty(resultMap.get(parseFormula))){
                            formulaValue = formulaValue.replace(parseFormula, resultMap.get(parseFormula));
                        }
                        /*for (IndicatorDetailsEntity indicatorDetailsEntity : indicatorDetailsEntities) {
                            //如果编号相同
                            if (indicatorDetailsEntity.getIndexNumber().equals(parseFormula)) {
                            }
                        }*/
                        //如果替换之后依然存在则判空
                        if (formulaValue.contains(parseFormula)) {
                            formulaValue = formulaValue.replace(parseFormula, "");
                        }
                    }
                    //公式参数集合
                    formulaModel.setParseFormula(list);

                    //公式描述
                    formulaModel.setFormulaDesc(formulaValue);
                } else {
                    //备注
                    formulaModel.setFormulaDesc(inportFormulaModel.getRemark());
                }
                /*
                    对象转json
                 */
                String formula = JSON.toJSONString(formulaModel);
                inportFormulaModel.setFormulaValue(formula);
                hashMap.put(inportFormulaModel.getFormulaId(),formula);
//                hashMap.putAll(map);
                reportFormsDataValueDao.updateFormula(formula,inportFormulaModel.getFormulaId());
            }
        }
//        reportFormsDataValueDao.updateFormulaMap(hashMap);
    }

    /**
     * 根据编码以及版本查询数据值信息
     *
     * @param tableCellSerialNumber 编码
     * @param calculatingTime       计算时间
     * @return 计算结果数据
     */
    @Override
    public List<ReportFormsDataValueEntity> selectBySerialNumberAndVersion(String tableCellSerialNumber, Date calculatingTime) {
        //根据编号以及计算时间查询该年月日得计算结果
        return reportFormsDataValueDao.selectBySerialNumberAndVersion(tableCellSerialNumber, calculatingTime);
    }

    /**
     * 根据计算版本删除报表计算数据
     *
     * @param calculatingTime 计算时间版本
     */
    @Override
    public void deleteByVersion(Date calculatingTime) {
        reportFormsDataValueDao.deleteByVersion(calculatingTime);
    }

    @Override
    public void doExportReportFormsDataValueByVersion(HttpServletResponse response, String reportFormsId, Date version) throws IOException {
        List<List<ReportFormsDataValueEntity>> lists = this.selectReportFormsDataValueByVersion(reportFormsId, version);


        SXSSFWorkbook wb = new SXSSFWorkbook();
        Sheet sh = wb.createSheet();
        for (int i = 0; i < lists.size(); i++) {
            List<ReportFormsDataValueEntity> reportFormsDataValueEntities = lists.get(i);
            int size = reportFormsDataValueEntities.size();

//            String[] titles = {"公式编号", "公式详细", "字段", "备注"};
            String[] titles = new String[size];
            for (int h = 0; h < reportFormsDataValueEntities.size(); h++) {
                ReportFormsDataValueEntity reportFormsDataValueEntity = reportFormsDataValueEntities.get(h);
                titles[h] = reportFormsDataValueEntity.getDataValue();
            }

            Row row = sh.createRow(i);
            CellStyle style = wb.createCellStyle();
            style.setFillForegroundColor(HSSFColor.HSSFColorPredefined.WHITE.getIndex());
            style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
            style.setBorderBottom(BorderStyle.THIN);
            style.setBorderLeft(BorderStyle.THIN);
            style.setBorderRight(BorderStyle.THIN);
            style.setBorderTop(BorderStyle.THIN);
            style.setAlignment(HorizontalAlignment.CENTER);

            // 第一行设置标题
            for (int k = 0; k < titles.length; k++) {
                String title = titles[k];
                Cell cell1 = row.createCell(k);
                cell1.setCellValue(title);
                cell1.setCellStyle(style);
            }
            for (int j = 0; j < size; j++) {
                sh.setColumnWidth(j, 6000);
            }
        }
        String fileName = "报表计算版本数据.xlsx";
        response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
        wb.write(response.getOutputStream());
        wb.close();
    }

    /**
     * 根据编号查询该编号以往的公式集合
     *
     * @param reportFormsSerialNumber 单元格编号
     * @return 公式集合
     */
    @Override
    public List<ReportFormsDataValueEntity> selectFormula(String reportFormsSerialNumber) {
        return reportFormsDataValueDao.selectFormula(reportFormsSerialNumber);
    }

    /**
     * 将报表数据值分组排序
     *
     * @param reportFormsDataValueEntities 报表数据值集合
     * @return 分组后得报表数据值集合
     */
    private List<List<ReportFormsDataValueEntity>> reportFormsDataValueEntitiesGroupSort(List<ReportFormsDataValueEntity> reportFormsDataValueEntities) {
        List<List<ReportFormsDataValueEntity>> reportFormsDataValueSortList = new ArrayList<>();
        //按照行号分组
        Map<Integer, List<ReportFormsDataValueEntity>> lineNumberKeyMap = reportFormsDataValueEntities.stream().collect(Collectors.groupingBy(ReportFormsDataValueEntity::getLineNumber));

        //遍历重新放入数据集合
        lineNumberKeyMap.forEach((k, v) -> {
            v.sort(Comparator.comparing(ReportFormsDataValueEntity::getColumnNumber));
            reportFormsDataValueSortList.add(v);
        });

        //将数据集合按照行号排序
        reportFormsDataValueSortList.sort(Comparator.comparing(o -> o.get(0).getLineNumber()));

        return reportFormsDataValueSortList;
    }
}